function define(obj, key, value) {
    Object.defineProperty(obj, key, {
        configurable: false,
        enumerable: true,
        writable: true,
        value,
    });
}

export default class ProductModel {
    public id: number | null = null;
    public display_price: number | null = null;
    public shop_id: number | null = null;
    public is_free: 0 | 1 = 0;
    public spec: { [specId: number]: Product.Spec } = {};
    public specIds: number[] = [];
    public end_time = '';
    public tag = '';
    public has_buy = 0;
    public buy_limit = 0;
    public status: 'on' | 'off' = 'off';

    public loadRaw(raw: Product.Detail) {
        this.id = raw.id;
        this.display_price = raw.display_price;
        this.shop_id = raw.shop_id;
        this.is_free = raw.is_free;
        this.status = raw.status;

        define(this, 'sales_volume', raw.sales_volume);
        define(this, 'description', raw.description);
        define(this, 'name', raw.name);
        define(this, 'cover', raw.cover);
        define(this, 'price', raw.price);
        define(this, 'attr', raw.attr);
        define(this, 'end_time', raw.end_time);
        define(this, 'specIds', raw.spec.map((item) => item.id));
        define(this, 'spec', {});
        for (const spec of raw.spec) {
            this.spec[spec.id] = spec;
        }
        this.end_time = raw.end_time;
        this.has_buy = raw.has_buy;
        this.buy_limit = raw.buy_limit;
        this.tag = raw.tag;
    }

    public getSpec(specId: number) {
        // console.log('getSpec');
        return this.spec[specId];
    }

    /**
     * 获得价格信息
     * @param specId 指定规格
     * @return { max: Money, min: Money } | null
     */
     public getPrice(specId: number) {
        // console.log('getPrice');
        const selectedSpec = specId ? this.spec[specId] : null;
        if (!selectedSpec) {
            let min = Infinity;
            let max = -1;
            if (!this.specIds) {
                return null;
            }
            this.specIds.forEach((specId) => {
                const spec = this.spec[specId];
                if (!spec) {
                    return;
                }
                const price = spec.price;
                if (price > max) {
                    max = price;
                }
                if (price < min) {
                    min = price;
                }
            });
            if (max === -1) {
                return null;
            } else {
                return {
                    min,
                    max,
                };
            }
        } else {
            return {
                min: selectedSpec.price,
                max: selectedSpec.price,
            };
        }
    }
}
